#include "macro.h"
#include "cmovepool.h"

using namespace std;

namespace sokoban{

MoveMap::iterator CMovePool::Insert
(
  T_POS     from,
  EMoveElem move,
  T_DIM     nBoardCol
)
{
  T_POS nextPos = from;

  // first, we construct the position to insert in the move pool, given the
  // starting point and the movement
  switch( move )
  {
    case M_U:
      nextPos = from - nBoardCol;
      break;
    case M_D:
      nextPos = from + nBoardCol;
      break;
    case M_L:
      nextPos = from - 1;
      break;
    case M_R:
      nextPos = from + 1;
      break;
    case M_NONE:
      break;
  }

  // then, we check if it is already in the pool
  LOG( L_CMOVEPOOL, "I : Trying to move from %i to %i with %c", from, nextPos, move );

  MoveMap::iterator it_next = moves->find( nextPos );

  if( it_next == moves->end() )
  {
    LOG( L_CMOVEPOOL, "\tMove to %i absent. Creating it.", nextPos );
    // if not, we insert it.
    // But we have to retrieve the complete previous move, in order to have
    // the complete path
    MoveMap::const_iterator it_prev = moves->find( from );


    string path = ( it_prev != moves->end() ?
                         (it_prev->second) + string(1,move) :
                         string(1,move) );

    // finally, we return an iterator on the newly inserted move.
    return (moves->insert( pair< T_POS, string >( nextPos, path ) )).first;
  }
  else
  {
    LOG( L_CMOVEPOOL, "\tMove to %i was already done. Returning.", nextPos );
    return moves->end();
  }
}

MoveMap::const_iterator CMovePool::CanGoThere( T_POS there ) const
{
  return moves->find( there );
}

vector< T_POS > CMovePool::ToVector() const
{
  vector< T_POS > result( moves->size() );

  MoveMap::const_iterator it;

  int i = 0;

  for( it = moves->begin() ; it != moves->end() ; it++ )
    result[ i++ ] = it->first; // this is a bit ugly.

  return result;
}

/* sokoban */ }
